package com.asiainfo.dacp.datastash.broker.listener;

import java.util.List;

import org.springframework.scheduling.annotation.Async;

import com.asiainfo.dacp.core.BeanFactory;
import com.asiainfo.dacp.datastash.broker.core.BrokerContext;
import com.asiainfo.dacp.datastash.broker.core.enums.UnitTaskStateEnum;
import com.asiainfo.dacp.datastash.broker.core.vo.StashUnitTask;
import com.asiainfo.dacp.datastash.broker.facade.UnitTaskFacade;
import com.asiainfo.dacp.datastash.broker.facade.state.UnitTaskStateLogService;
import com.asiainfo.dacp.datastash.broker.tracelog.StashTraceLogVo;
import com.asiainfo.dacp.datastash.broker.tracelog.StashTraceLogger;

/**
 *
 * 监听子任务/分片的等待队列（unit_task_wait_queue）
 *
 * 获取任务后，判断task的依赖是否到达，到达后交由任务分配器去执行
 *
 * @author MeiKefu
 * @date 2017-12-23
 */
public class UnitTaskWaitQueueListener extends AbstractQueueListener {

	private String clzName = this.getClass().getSimpleName();

	@Async
	protected void handle() {
		StashTraceLogger tracelog = BeanFactory.getBean(StashTraceLogger.class);
		UnitTaskFacade unitTaskFacade = BeanFactory.getBean(UnitTaskFacade.class);

		UnitTaskStateLogService taskLog = BeanFactory.getBean(UnitTaskStateLogService.class);

		StashUnitTask stashUnitTask = unitTaskFacade.fetchWaitingTask();

		if (stashUnitTask != null) {
			tracelog.info(
					StashTraceLogVo.buildStashTraceLogVo(stashUnitTask, clzName, "taskWaitQueue:fetch", "判断任务依赖"));
			// 判断任务依赖
			List<String> relayTaskIds = stashUnitTask.getPreTaskProcIds();

			if (relayTaskIds != null && relayTaskIds.size() > 0) {
				for (String relayTaskId : relayTaskIds) {
					if (!unitTaskFacade.isUnitTaskSuccess(relayTaskId)) {
						tracelog.info(new StashTraceLogVo(clzName, "taskWaitQueue:depJuding",
								"依赖任务:" + relayTaskIds + "未执行完成，重新入队"));
						unitTaskFacade.reQueueTask(stashUnitTask);
						// TODO 需要设置重新入队时间延时
						return;
					}
				}
			} else {
				tracelog.info(StashTraceLogVo.buildStashTraceLogVo(stashUnitTask, clzName, "taskWaitQueue:depJuding",
						"没有任务依赖直接启动"));
			}

			taskLog.update(stashUnitTask, UnitTaskStateEnum.BLOCKED_RESOURCE, BrokerContext.getInstance().getBrokerId(),
					BrokerContext.getInstance().getBrokerIp());
			// 依赖都到达，放入待分配的列表中
			unitTaskFacade.dispatchTask(stashUnitTask);

		} else {
			tracelog.debug(StashTraceLogVo.buildStashTraceLogVo(clzName, "taskWaitQueue:fetch:fail", "未获取分片的队列", null,
					null, null));
		}
	}

}
